<?php
declare (strict_types=1);

namespace app\course\logic\agent\admin;

use app\admin\logic\user\Account;
use app\common\exception\LogicException;
use app\admin\logic\system\Log;
use app\common\logic\Attach;
use app\common\logic\category\Category;
use app\common\model\payment\PaymentOrderItem;
use app\course\logic\base\admin\Course;
use app\course\logic\base\admin\CourseStudent;
use app\course\logic\classes\admin\Classes as ClassesLogic;
use app\course\logic\live\admin\Live as LiveLogic;
use app\course\logic\live\admin\LiveSmall as LiveSmallLogic;
use app\course\logic\video\admin\Video as VideoLogic;
use app\course\model\agent\admin\CourseAgent as CourseAgentModel;
use app\course\model\agent\admin\CourseAgentLog as CourseAgentLogModel;
use app\school\model\school\School;
use think\facade\Request;

/**
 * 后台管理逻辑层
 */
class CourseAgent extends CourseAgentModel
{
    /**
     * 课程代理--首页列表
     *
     * @param $map
     * @return mixed
     */
    public function getList($map)
    {
        $cids = $this->group(['course_id'])->order('create_time', 'desc')->column('course_id');
        if ($cids) {
            $map[] = ['id', 'IN', $cids];
        } else {
            $map[] = ['id', '=', 0];
        }

        return app(Course::class)->with(['cover_url'])->where($map)->order('create_time', 'desc')->paginate($this->getListRows())->append(['course_type_text'])->each(function ($item) {
            $item->cates = app(Category::class)->parseTitle($item->category, 0, $item->fullcategorypath ?? []);
        });
    }

    /**
     * 课程代理--详情列表
     *
     * @param $map
     * @return mixed
     */
    public function getInfoList($map)
    {
        $list = $this->with(['school', 'cost_price'])
            ->where($map)
            ->order('create_time', 'desc')
            ->paginate($this->getListRows())
            ->append(['term_time', 'course_type_text'])
            ->each(function ($i) {
                // 查询订单数据
                $order          = app(PaymentOrderItem::class)->withJoin(['success_main'])->where('__TABLE__.mhm_id', $i->mhm_id)->where('product_id', $i->course_id)->where('is_agent', 1)->where('successMain.status', 'IN', '20,30,40')->select()->toArray();
                $i->onlinenum   = count($order) > 0 ? count($order) : 0;
                $i->linenum     = app(CourseStudent::class)->where('course_id', $i->course_id)->where('from', 1)->where('mhm_id', $i->mhm_id)->count();
                $i->ordernum    = $i->onlinenum + $i->linenum;
                $i->order_price = count($order) > 0 ? array_sum(array_column($order, 'payment')) : 0;
            });

        return $list;
    }

    /**
     * 课程代理库--记录列表
     *
     * @param $data
     * @return mixed
     */
    public function getRecordList($data)
    {
        $courseId = $data['course_id'];
        $map[]    = ['course_id', 'LIKE', '%' . $courseId . '%'];

        $list = app(CourseAgentLogModel::class)->with(['user_name'])->where($map)->order('create_time', 'desc')->paginate($this->getListRows())->append(['status_text'])->each(function ($i) use ($courseId) {
            // 手动组装内容
            $course_title = app(Course::class)->whereId($courseId)->value('title');
            $school_name  = app(School::class)->where('id', 'IN', $i->agent_mhm_id)->column('title');
            $school_name  = $school_name ? implode('、', $school_name) : '';
            $i->content   = '管理员[' . $i->user_name . ']将课程《' . $course_title . '》' . $i->status_text . '给机构： ' . $school_name;
        });

        return $list;
    }

    /**
     * 代理记录--课程派发
     *
     * @param array $data
     * @return Video
     */
    public function syncVideo(array $data)
    {
        // 取得验证器
        $this->getValidate()->failException()->check($data);

        $saveAll = $this->buildSaveData($data);
        // 如果有数据需要保存，则进行保存操作
        if (!empty($saveAll)) {
            $this->startTrans();
            try {
                // 获取数据
                $school_ids   = $this->buildSaveData($data, 2);
                $agent_mhm_id = count($school_ids) > 0 ? implode(',', $school_ids) : '';
                // 删除原有数据
                $delete = $this->where('course_id', '=', $data['vid'])->where('mhm_id', 'IN', $agent_mhm_id)->select();
                if (!$delete->delete()) throw new LogicException('派发失败');
                // 添加数据
                $res = $this->saveAll($saveAll);
                if ($res->isEmpty()) throw new LogicException('派发失败');
                // 记录代理记录
                $logData = [
                    'mhm_id'        => request()->mhm_id,
                    'agent_mhm_id'  => $agent_mhm_id,
                    'course_id'     => $data['vid'],
                    'admin_user_id' => request()->admin_user_id,
                    'status'        => 1,
                    'user_ip'       => Request::ip(),
                    'course_type'   => $data['course_type'],
                ];
                $log     = app(CourseAgentLogModel::class)->create($logData);
                if ($log->isEmpty()) throw new LogicException('派发失败');

                // 系统日志
                $course_title = app(Course::class)->whereId($data['vid'])->value('title');
                $school_name  = app(School::class)->where('id', 'IN', $agent_mhm_id)->column('title');
                $school_name  = $school_name ? implode('、', $school_name) : '';
                Log::write('将课程【' . $course_title . '】代理给机构【' . $school_name . '】', 'course_agent', 'create', true);

                $this->commit();
            } catch (LogicException $error) {
                $this->rollback();
                throw $error;
            }

            return $this;
        } else {
            throw new LogicException('代理失败');
        }
    }

    /**
     * 课程代理库--课程代理操作处理
     *
     * @param array $data
     * @param int   $type
     * @return array
     */
    protected function buildSaveData(array $data, int $type = 1)
    {
        $saveAll   = [];
        $err_count = [];
        // 获取当前时间
        $now_time  = strtotime(date('Y-m-d ', Request::time()) . '00:00:00');
        $term_time = $now_time + $data['term'] * 24 * 60 * 60;
        foreach ($data['school'] as $val) {
            if ($val != 1) {
                $have = $this
                    ->where('course_id', $data['vid'])
                    ->where('mhm_id', $val)
                    ->where('term_time', '>', Request::time())
                    ->findOrEmpty();

                if ($have->isEmpty()) {
                    if ($type == 1) {
                        $saveAll[] = [
                            'course_id'   => $data['vid'],
                            'mhm_id'      => $val,
                            'term'        => $data['term'],
                            'term_time'   => $term_time,
                            'course_type' => $data['course_type'],
                            'price'       => $data['price'],
                        ];
                    } else {
                        $saveAll[] = $val;
                    }
                } else {
                    array_push($err_count, $val);
                }
            }
        }

        // 判断机构是否重复添加
        if (count($err_count) > 0) {
            // 获取机构名称
            $school_name = app(School::class)->where('id', 'IN', $err_count)->column('title');
            // 组装机构名称
            $school_name = count($school_name) > 0 ? implode('、', $school_name) : '';
            if ($school_name) throw new LogicException('机构：' . $school_name . ' 已代理，请重新选择');
        }

        return $saveAll;
    }

    /**
     * 删除代理课程
     *
     * @param $id
     * @return void
     */
    public function deleteAgent($id)
    {
        $video = $this->whereId($id)->findOrFail();

        $this->startTrans();
        try {
            // 删除
            if (!$video->delete()) {
                throw new LogicException('删除失败');
            }
            // 记录
            $logData = [
                'mhm_id'        => request()->mhm_id,
                'agent_mhm_id'  => $video->mhm_id,
                'course_id'     => $video->course_id,
                'admin_user_id' => request()->admin_user_id,
                'status'        => 0,
                'user_ip'       => Request::ip()
            ];
            $log     = app(CourseAgentLogModel::class)->create($logData);
            if ($log->isEmpty()) throw new LogicException('删除失败');

            // 系统日志
            $admin        = '管理员【' . request()->user->user_name . '/' . request()->user->id . '】';
            $course_title = app(Course::class)->whereId($video->course_id)->value('title');
            $school_name  = app(School::class)->whereId($video->mhm_id)->value('title');
            Log::write($admin . '删除了课程【' . $course_title . '】的代理机构【' . $school_name . '】', 'course_agent', 'delete');

            $this->commit();
        } catch (LogicException $error) {
            $this->rollback();
            throw $error;
        }
    }

    /**
     * 机构派发--批量添加课程
     *
     * @param int   $id
     * @param array $data
     * @return $this
     */
    public function addSchoolCourse(int $id, array $data)
    {
        $saveAll = $this->buildAddCourse($id, $data);
        // 如果有数据需要保存，则进行保存操作
        if (!empty($saveAll)) {
            $this->startTrans();
            try {
                // 获取数据
                $course_ids = $this->buildAddCourse($id, $data, 2);
                $course_ids = count($course_ids) > 0 ? implode(',', $course_ids) : '';
                // 添加数据
                $res = $this->saveAll($saveAll);
                if ($res->isEmpty()) throw new LogicException('派发失败');
                // 记录代理记录
                $logData = [
                    'mhm_id'        => request()->mhm_id,
                    'agent_mhm_id'  => $id,
                    'course_id'     => $course_ids,
                    'admin_user_id' => request()->admin_user_id,
                    'status'        => 1,
                    'user_ip'       => Request::ip(),
                ];
                $log     = app(CourseAgentLogModel::class)->create($logData);
                if ($log->isEmpty()) throw new LogicException('派发失败');

                // 系统日志
                $course_title = app(Course::class)->where('id', 'IN', $course_ids)->column('title');
                $course_title = $course_title ? implode('、', $course_title) : '';
                $school_name  = app(School::class)->whereId($id)->value('title');
                Log::write('将课程【' . $course_title . '】代理给机构【' . $school_name . '】', 'course_agent', 'create', true);

                $this->commit();
            } catch (LogicException $error) {
                $this->rollback();
                throw $error;
            }

            return $this;
        } else {
            throw new LogicException('代理失败');
        }
    }

    /**
     * 机构派发--批量添加课程--课程代理操作处理
     *
     * @param int   $id
     * @param array $data
     * @param int   $type
     * @return array
     */
    protected function buildAddCourse(int $id, array $data, int $type = 1)
    {
        $saveAll = [];
        // 获取当前时间
        $now_time  = strtotime(date('Y-m-d ', Request::time()) . '00:00:00');
        $term_time = $now_time + $data['term'] * 24 * 60 * 60;
        foreach ($data['course_ids'] as $val) {
            $have = $this
                ->where('course_id', $val)
                ->where('mhm_id', $id)
                ->where('term_time', '>', Request::time())
                ->findOrEmpty();

            if ($have->isEmpty()) {
                if ($type == 1) {
                    $course    = app(Course::class)->whereId($val)->field('course_type,price')->findOrEmpty();
                    $saveAll[] = [
                        'course_id'   => $val,
                        'mhm_id'      => $id,
                        'term'        => $data['term'],
                        'term_time'   => $term_time,
                        'course_type' => $course->course_type,
                        'price'       => $course->price,
                    ];
                } else {
                    $saveAll[] = $val;
                }
            }
        }

        return $saveAll;
    }

    /**
     * 课程分销--机构数据列表
     *
     * @param $mhm_id
     * @param $map
     * @return array
     */
    public function getAgentSchoolList($mhm_id, $map)
    {
        $agentMap = [];
        $field    = 'a.*,c.title,c.cover,c.course_type,c.price as cost_price,course_live_type as live_type';
        $list     = $this->alias('a')
            ->leftJoin('course c', 'a.course_id=c.id')
            ->where('a.mhm_id', $mhm_id)
            ->where('a.term_time', '>', Request::time())
            ->where($agentMap)
            ->where($map)
            ->order('a.create_time', 'desc')
            ->field($field)
            ->paginate($this->getListRows())
            ->append(['course_type_text'])
            ->each(function ($i) {
                $i->cover_url = app(Attach::class)->where('id', $i->cover)->findOrEmpty()->getAttr('fileurl');
                $i->cates     = app(Category::class)->parseTitle($i->mhm_category, 0, $i->mhm_fullcategorypath ?? []);
                // 直播小班课处理
                if ($i->course_type == 2 && $i->live_type == 2) {
                    $i->course_type = 3;
                }
            });

        return $list;
    }

    /**
     * 课程分销--机构数据详情
     *
     * @param       $mhm_id
     * @param       $post
     * @return array
     */
    public function getSchoolCourseInfo($mhm_id, $post)
    {
        $field = 'id,title,fullcategorypath,category,cover,price as cost_price';
        $type  = $post['type'];
        $aid   = $post['aid'];
        switch ($type) {
            case 2:
                $mod = app(LiveLogic::class);
                break;
            case 3:
                $mod  = app(LiveSmallLogic::class);
                $type = 2;
                break;
            case 4:
                $mod = app(ClassesLogic::class);
                break;
            case 1:
            default:
                $mod = app(VideoLogic::class);
                break;
        }
        $data = $mod->withoutGlobalScope(['mhm'])->with(['cover_url', 'agent_info' => function ($query) use ($mhm_id, $aid) {
            $query->where('mhm_id', $mhm_id)->where('id', $aid);
        }])
            ->whereId($post['vid'])
            ->where('course_type', $type)
            ->field($field)
            ->findOrEmpty();
        if (!$data->isEmpty()) {
            $cates       = app(Category::class)->parseTitle($data->category, 0, $data->fullcategorypath ?? []);
            $data->cates = count($cates) > 0 ? $cates[0] : '';
            // 分类处理
            $data->cate = $data->mhm_fullcategorypath[0];
        }

        return $data;
    }

    /**
     * 课程分销--机构--课程信息保存
     *
     * @param       $mhm_id
     * @param array $data
     * @return void
     */
    public function schoolUpdate($mhm_id, array $data)
    {
        $agent = $this->where('mhm_id', $mhm_id)->where('id', $data['aid'])->where('course_id', $data['vid'])->findOrFail();
        // 分类处理
        $mhm_fullcategorypath        = [];
        $mhm_fullcategorypath[]      = $data['cate'] ?? [];
        $agent->mhm_fullcategorypath = $mhm_fullcategorypath;
        $agent->mhm_category         = $data['cate'] ?? [];
        $agent->price                = $data['price'] ?? 0;
        $agent->status               = 1;

        if (!$agent->save()) {
            throw new LogicException('编辑失败');
        }
    }

    /**
     * 课程分销--学员顶部统计
     *
     * @param $id
     * @param $mhm_id
     * @return mixed
     */
    public function getSchoolStatistic($id, $mhm_id)
    {
        $data = [];

        // 浏览数
        $data['view_count'] = app(Video::class)->withoutGlobalScope(['mhm'])->whereId($id)->value('view_count');
        // 线上订单
        $data['online_order_count'] = app(PaymentOrderItem::class)->withJoin(['success_main'])->where('__TABLE__.mhm_id', $mhm_id)->where('product_id', $id)->where('is_agent', 1)->where('successMain.status', 'IN', '20,30,40')->count();
        // 线下订单
        $data['offline_order_count'] = app(CourseStudent::class)->where('course_id', $id)->where('from', 1)->where('mhm_id', $mhm_id)->count();
        // 订单总数
        $data['order_count'] = $data['online_order_count'] + $data['offline_order_count'];
        // 订单额
        $data['order_amount'] = app(PaymentOrderItem::class)->withJoin(['success_main'])->where('__TABLE__.mhm_id', $mhm_id)->where('product_id', $id)->where('is_agent', 1)->where('successMain.status', 'IN', '20,30,40')->sum('payment');

        return $data;
    }

    /**
     * 编辑指定字段
     *
     * @param $id
     * @param $field
     * @param $value
     * @return mixed
     */
    public function editField($id, $field, $value)
    {
        // 信息
        $agent = $this->findOrFail($id);
        if (strtotime($agent->term_time) <= Request::time()) {
            throw new LogicException("该课程代理已到期");
        }

        // 数据修改
        $agent->$field = $value;

        if (!$agent->save()) {
            throw new LogicException("更新失败");
        }

        // 返回值
        return $agent;
    }

    /**
     * 课程代理库--机构--代理课程列表
     *
     * @param $map
     * @return mixed
     */
    public function getSchoolCourseInList($map)
    {
        $list = $this->with(['cost_price'])
            ->where($map)
            ->order('create_time', 'desc')
            ->paginate($this->getListRows())
            ->append(['term_time', 'course_type_text'])
            ->each(function ($i) {
                // 查询订单数据
                $order          = app(PaymentOrderItem::class)->withJoin(['success_main'])->where('__TABLE__.mhm_id', $i->mhm_id)->where('product_id', $i->course_id)->where('is_agent', 1)->where('successMain.status', 'IN', '20,30,40')->select()->toArray();
                $i->onlinenum   = count($order) > 0 ? count($order) : 0;
                $i->linenum     = app(CourseStudent::class)->where('course_id', $i->course_id)->where('from', 1)->where('mhm_id', $i->mhm_id)->count();
                $i->ordernum    = $i->onlinenum + $i->linenum;
                $i->order_price = count($order) > 0 ? array_sum(array_column($order, 'payment')) : 0;
            });

        return $list;
    }

    /**
     * 是否有机构代理该课程
     *
     * @param int $courseId
     * @param int $courseType
     * @return bool
     */
    public static function isSchoolAgent(int $courseId, int $courseType)
    {
        $agentId = app(CourseAgentModel::class)->where('course_id', $courseId)->where('course_type', $courseType)->where('term_time', '>', Request::time())->value('id');

        return boolval($agentId);
    }
}
